#include "../Renderer/Renderer.h"

namespace Nitro::Renderer {

void BufferDescriptor::appendAttribute(uint32_t offset, uint32_t stride,
                                       Format format)
{
    vertexAttribs.push_back(
        {(uint32_t)vertexAttribs.size(), offset, stride, format});
}
void BufferDescriptor::appendAttribute(uint32_t location, uint32_t offset,
                                       uint32_t stride, Format format)
{
    vertexAttribs.push_back({location, offset, stride, format});
}

Buffer CreateBuffer(const BufferDescriptor& desc, const void* data)
{
    Buffer buffer;
    if (desc.bindFlags == VertexBuffer)
    {
        glCreateVertexArrays(1, &buffer.vao);
        glCreateBuffers(1, &buffer.vbo);
        glNamedBufferStorage(buffer.vbo, desc.size, data, 0);
        glBindVertexArray(buffer.vao);
        glBindBuffer(GL_ARRAY_BUFFER, buffer.vbo);

        for (auto& vertexAttrib : desc.vertexAttribs)
        {
            glVertexArrayVertexBuffer(buffer.vao, vertexAttrib.location,
                                      buffer.vbo, vertexAttrib.offset,
                                      vertexAttrib.stride);
            
            switch (vertexAttrib.format)
            {
                
                case R32Float:
                    glVertexArrayAttribFormat(buffer.vao, vertexAttrib.location,
                                              1, GL_FLOAT, false, 0);
                    break;
                case RG32Float:
                    glVertexArrayAttribFormat(buffer.vao, vertexAttrib.location,
                                              2, GL_FLOAT, false, 0);
                    break;
                case RGB32Float:
                    glVertexArrayAttribFormat(buffer.vao, vertexAttrib.location,
                                              3, GL_FLOAT, false, 0);
                    break;
                case RGBA32Float:
                    glVertexArrayAttribFormat(buffer.vao, vertexAttrib.location,
                                              4, GL_FLOAT, false, 0);
                    break;
                default: break;
            }
            glEnableVertexArrayAttrib(buffer.vao, vertexAttrib.location);
        }
        
    }
    else if (desc.bindFlags == IndexBuffer)
    {
        GLuint id;
        glCreateBuffers(1, &id);
        buffer.id = id;
        glNamedBufferStorage(buffer.id, desc.size, data, 0);
    }
    return buffer;
}

} // namespace Nitro::Renderer